package PowerWord.Core.Data;

import java.io.*;
import java.util.ArrayList;

import PowerWord.Core.ReciteEffect.WordProperty;
import PowerWord.Core.ReciteEffect.WordProperty.FamiliarLevel;

public class WordList{
	
	public enum SearchFlag {Similiar, Equal, Larger, Less};

	String mListFileName = "";

	ArrayList<String> words = new ArrayList<String>();
	byte[] flags = null;
	
	public void Import(String listName) {
		if(!mListFileName.equals(listName)){
			Export();
		}
		words.clear();
		try {
			// read words
			BufferedReader reader = new BufferedReader(new FileReader(Defines.ListDirectory + listName));
			String word;
			while((word = reader.readLine()) != null){
				words.add(word);
			}
			// read flags
			DataInputStream saveData = new DataInputStream(new FileInputStream(Defines.SaveDirectory + listName));
			flags = new byte[words.size()];
			saveData.read(flags);
			saveData.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		mListFileName = listName;
	}
	
	public void Export() {
		try {
			new File(Defines.SaveDirectory).mkdir();
			DataOutputStream saveData = new DataOutputStream(new FileOutputStream(Defines.SaveDirectory + mListFileName));
			saveData.write(flags);
			saveData.close();
		}
		catch (IOException e){
			e.printStackTrace();
		}
	}

	public Integer[] GetSubList(int left, int right, int flag) {
		assert(left >= 0 && right > left && right < words.size());
		ArrayList<Integer> tempList = new ArrayList<Integer>();
		for(int i=left; i<=right; ++i) {
			if((flags[i] & flag) == flag) {
				tempList.add(i);					
			}
		}
		Integer[] rev = null;
		int count = tempList.size();
		if(count > 0){
			rev = new Integer[tempList.size()];
			tempList.toArray(rev);
		}
		return rev;
	}
	
	public int GetCount() {
		return words.size();
	}

	public String GetItem(int position) {
		return words.get(position);
	}
	
	public void SetItemProperty(int pos, byte flag){
		flags[pos] = WordProperty.SetWordProperty(flags[pos], flag);
	}
	
	public void SetItemProperty(int pos, FamiliarLevel e){
		flags[pos] = WordProperty.SetFamiliarLevel(flags[pos], e);
	}
	
	public int GetItemFamiliar(int pos){
		return WordProperty.GetFimiliarLevel(flags[pos]);
	}
	
	public int Search(String item, SearchFlag searchFlag) {
		int left = 0, right = words.size(), pos = (left+right)/2;
		int cmpVal = 0;
		while ((cmpVal=item.compareTo(words.get(pos))) != 0 && left <= right)
		{
			if (cmpVal < 0)
			{
				right = pos - 1;
				pos = (left + right) / 2;
			} 
			else
			{
				left = pos + 1;
				pos = (left + right) / 2;
			}
		}
		switch(searchFlag) {
		case Equal:
			return cmpVal == 0 ? pos : -1;
		case Larger:
			return cmpVal <= 0 ? pos : pos + 1;
		case Less:
			return cmpVal >= 0 ? pos : pos - 1;
		default:
			return pos;
		}
	}
}
